package cn.edu.cug.cs.gtl.apis.ui.datake.devicetree;

import cn.edu.cug.cs.gtl.apis.ui.AbstractApplication;
import cn.edu.cug.cs.gtl.apis.ui.tree.Tree;
import cn.edu.cug.cs.gtl.apis.ui.tree.TreeNodeData;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Vector;

public class DeviceTree extends Tree {

    public enum NodeType{
        DATA_CLUSTER_NODE,
        STORAGE_CLUSTER_NODE,
        HDFS_CLUSTER_NODE,
        MINIO_CLUSTER_NODE,
        POSTGRESQL_CLUSTER_NODE,
        MYSQL_CLUSTER_NODE,
        ORACLE_CLUSTER_NODE,
        MONGODB_CLUSTER_NODE,

        COMPUTING_CLUSTER_NODE,
        SPARK_CLUSTER_NODE,
        FLINK_CLUSTER_NODE,

        SEARCH_CLUSTER_NODE,
        ELASTICSEARCH_CLUSTER_NODE,
        SOLR_CLUSTER_NODE,
        CACHE_CLUSTER_NODE,
        REDIS_CLUSTER_NODE,
        MEMCACHED_CLUSTER_NODE,
        MESSAGE_CLUSTER_NODE,
        KAFKA_CLUSTER_NODE,
        RABBITMQ_CLUSTER_NODE,
        CONNECTION_NODE
    };

    private JPopupMenu popupMenu = new JPopupMenu();
    private JPopupMenu dataClusterNodePopupMenu = new JPopupMenu();
    private JPopupMenu storageClusterNodePopupMenu = new JPopupMenu();
    private JPopupMenu computingClusterNodePopupMenu = new JPopupMenu();
    private JPopupMenu searchClusterNodePopupMenu = new JPopupMenu();
    private JPopupMenu messageClusterNodePopupMenu = new JPopupMenu();
    private JPopupMenu cacheClusterNodePopupMenu = new JPopupMenu();
    private JPopupMenu storageChildNodePopupMenu = new JPopupMenu();
    static ResourceBundle resourceBundle=ResourceBundle.getBundle("uiapi_resource", Locale.getDefault());

    /**
     * Returns a <code>JTree</code> with a sample model.
     * The default model used by the tree defines a leaf node as any node
     * without children.
     */
    public DeviceTree() {
    }

    /**
     * Returns a <code>JTree</code> with each element of the
     * specified array as the
     * child of a new root node which is not displayed.
     * By default, the tree defines a leaf node as any node without
     * children.
     *
     * @param value an array of <code>Object</code>s
     */
    public DeviceTree(Object[] value) {
        super(value);
    }

    /**
     * Returns a <code>JTree</code> with each element of the specified
     * <code>Vector</code> as the
     * child of a new root node which is not displayed. By default, the
     * tree defines a leaf node as any node without children.
     *
     * @param value a <code>Vector</code>
     */
    public DeviceTree(Vector<?> value) {
        super(value);
    }

    /**
     * Returns a <code>JTree</code> created from a <code>Hashtable</code>
     * which does not display with root.
     * Each value-half of the key/value pairs in the <code>HashTable</code>
     * becomes a child of the new root node. By default, the tree defines
     * a leaf node as any node without children.
     *
     * @param value a <code>Hashtable</code>
     */
    public DeviceTree(Hashtable<?, ?> value) {
        super(value);
    }

    /**
     * Returns a <code>JTree</code> with the specified
     * <code>TreeNode</code> as its root,
     * which displays the root node.
     * By default, the tree defines a leaf node as any node without children.
     *
     * @param root a <code>TreeNode</code> object
     */
    public DeviceTree(TreeNode root) {
        super(root);
        this.popupMenu=createPopupMenuForConnectionNode();
    }

    /**
     * Returns a <code>JTree</code> with the specified <code>TreeNode</code>
     * as its root, which
     * displays the root node and which decides whether a node is a
     * leaf node in the specified manner.
     *
     * @param root               a <code>TreeNode</code> object
     * @param asksAllowsChildren if false, any node without children is a
     *                           leaf node; if true, only nodes that do not allow
     *                           children are leaf nodes
     */
    public DeviceTree(TreeNode root, boolean asksAllowsChildren) {
        super(root, asksAllowsChildren);
    }

    /**
     * Returns an instance of <code>JTree</code> which displays the root node
     * -- the tree is created using the specified data model.
     *
     * @param newModel the <code>TreeModel</code> to use as the data model
     */
    public DeviceTree(TreeModel newModel) {
        super(newModel);
    }

    public  JPopupMenu getPopupMenu(){
        return popupMenu;
    }

    public void setPopupMenu(JPopupMenu popupMenu) {
        popupMenu = popupMenu;
    }

    public JPopupMenu getDataClusterNodePopupMenu() {
        return dataClusterNodePopupMenu;
    }

    public void setDataClusterNodePopupMenu(JPopupMenu dataClusterNodePopupMenu) {
        this.dataClusterNodePopupMenu = dataClusterNodePopupMenu;
    }

    public JPopupMenu getStorageClusterNodePopupMenu() {
        return storageClusterNodePopupMenu;
    }

    public void setStorageClusterNodePopupMenu(JPopupMenu storageClusterNodePopupMenu) {
        this.storageClusterNodePopupMenu = storageClusterNodePopupMenu;
    }

    public JPopupMenu getComputingClusterNodePopupMenu() {
        return computingClusterNodePopupMenu;
    }

    public void setComputingClusterNodePopupMenu(JPopupMenu computingClusterNodePopupMenu) {
        this.computingClusterNodePopupMenu = computingClusterNodePopupMenu;
    }

    public JPopupMenu getSearchClusterNodePopupMenu() {
        return searchClusterNodePopupMenu;
    }

    public void setSearchClusterNodePopupMenu(JPopupMenu searchClusterNodePopupMenu) {
        this.searchClusterNodePopupMenu = searchClusterNodePopupMenu;
    }

    public JPopupMenu getMessageClusterNodePopupMenu() {
        return messageClusterNodePopupMenu;
    }

    public void setMessageClusterNodePopupMenu(JPopupMenu messageClusterNodePopupMenu) {
        this.messageClusterNodePopupMenu = messageClusterNodePopupMenu;
    }

    public JPopupMenu getCacheClusterNodePopupMenu() {
        return cacheClusterNodePopupMenu;
    }

    public void setCacheClusterNodePopupMenu(JPopupMenu cacheClusterNodePopupMenu) {
        this.cacheClusterNodePopupMenu = cacheClusterNodePopupMenu;
    }

    public JPopupMenu getStorageChildNodePopupMenu() {
        return storageChildNodePopupMenu;
    }

    public void setStorageChildNodePopupMenu(JPopupMenu storageChildNodePopupMenu) {
        this.storageChildNodePopupMenu = storageChildNodePopupMenu;
    }

    public static DeviceTree create(AbstractApplication theApp){

        //ResourceBundle resourceBundle=ResourceBundle.getBundle("uiapi_resource", Locale.getDefault());

        String s = resourceBundle.getString("data.device.data_cluster");
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new TreeNodeData(s,s,true));
        s = resourceBundle.getString("data.device.storage_cluster");
        DefaultMutableTreeNode node1 = new DefaultMutableTreeNode(new TreeNodeData(s,s,true));
//        StorageCluster sc = StorageCluster.newBuilder().setName("StorageCluster").build();
//        node1.setUserObject(sc);
//        DefaultMutableTreeNode node11 = new DefaultMutableTreeNode("HDFS");
//        DefaultMutableTreeNode node12 = new DefaultMutableTreeNode("MinIO");
//        DefaultMutableTreeNode node13 = new DefaultMutableTreeNode("PostgreSQL");
//        DefaultMutableTreeNode node14 = new DefaultMutableTreeNode("MySQL");
//        DefaultMutableTreeNode node15 = new DefaultMutableTreeNode("Oracle");
//        DefaultMutableTreeNode node16 = new DefaultMutableTreeNode("MongoDB");
//        node1.add(node11);
//        node1.add(node12);
//        node1.add(node13);
//        node1.add(node14);
//        node1.add(node15);
//        node1.add(node16);
        String supports = resourceBundle.getString("data.device.storage_cluster.supports");
        String[] ss = supports.split(",");
        for(String i:ss){
            node1.add(new DefaultMutableTreeNode(new TreeNodeData(i,i,true)));
        }

        s = resourceBundle.getString("data.device.computing_cluster");
        DefaultMutableTreeNode node2 = new DefaultMutableTreeNode(new TreeNodeData(s,s,true));

//        DefaultMutableTreeNode node21 = new DefaultMutableTreeNode("Spark");
//        DefaultMutableTreeNode node22 = new DefaultMutableTreeNode("Flink");
//        node2.add(node21);
//        node2.add(node22);
        supports = resourceBundle.getString("data.device.computing_cluster.supports");
        ss = supports.split(",");
        for(String i:ss){
            node2.add(new DefaultMutableTreeNode(new TreeNodeData(i,i,true)));
        }
        s=resourceBundle.getString("data.device.search_cluster");
        DefaultMutableTreeNode node3 = new DefaultMutableTreeNode(new TreeNodeData(s,s,true));
//        DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("ElasticSearch");
//        DefaultMutableTreeNode node32 = new DefaultMutableTreeNode("Apache Solr");
//        node3.add(node31);
//        node3.add(node32);
        supports = resourceBundle.getString("data.device.search_cluster.supports");
        ss = supports.split(",");
        for(String i:ss){
            node3.add(new DefaultMutableTreeNode(new TreeNodeData(i,i,true)));
        }

        s = resourceBundle.getString("data.device.message_cluster");
        DefaultMutableTreeNode node4 = new DefaultMutableTreeNode(new TreeNodeData(s,s,true));
//        DefaultMutableTreeNode node41 = new DefaultMutableTreeNode("Kafka");
//        DefaultMutableTreeNode node42 = new DefaultMutableTreeNode("RabbitMQ");
//        node4.add(node41);
//        node4.add(node42);
        supports = resourceBundle.getString("data.device.message_cluster.supports");
        ss = supports.split(",");
        for(String i:ss){
            node4.add(new DefaultMutableTreeNode(new TreeNodeData(i,i,true)));
        }
        s = resourceBundle.getString("data.device.cache_cluster");
        DefaultMutableTreeNode node5 = new DefaultMutableTreeNode(new TreeNodeData(s,s,true));
//        DefaultMutableTreeNode node51 = new DefaultMutableTreeNode("Redis");
//        DefaultMutableTreeNode node52 = new DefaultMutableTreeNode("Memcached");
//        node5.add(node51);
//        node5.add(node52);
        supports = resourceBundle.getString("data.device.cache_cluster.supports");
        ss = supports.split(",");
        for(String i:ss){
            node5.add(new DefaultMutableTreeNode(new TreeNodeData(i,i,true)));
        }
        root.add(node1);
        root.add(node2);
        root.add(node3);
        root.add(node4);
        root.add(node5);
        DeviceTree tree = new DeviceTree(root);
        return tree;
    }

    public static NodeType getNodeType(DefaultMutableTreeNode node){
        return NodeType.CONNECTION_NODE;
    }

    public static boolean isConnectionNode(DefaultMutableTreeNode node){
        return true;
    }

    public static JPopupMenu createPopupMenuForConnectionNode(){
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem menuItem = new JMenuItem(resourceBundle.getString("popupmenu.data.device.add"));
        popupMenu.add(menuItem);
        menuItem = new JMenuItem(resourceBundle.getString("popupmenu.data.device.delete"));
        popupMenu.add(menuItem);
        menuItem = new JMenuItem(resourceBundle.getString("popupmenu.data.device.rename"));
        popupMenu.add(menuItem);
        return popupMenu;
    }
    public static JPopupMenu createPopupMenuForNonConnectionNode(){
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem menuItem = new JMenuItem(resourceBundle.getString("popupmenu.data.device.add"));
        popupMenu.add(menuItem);
        return popupMenu;
    }
}
